package com.hjk.waibao.mj.util;

import cn.hutool.core.util.ClassUtil;
import com.alibaba.fastjson.JSONObject;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

/**
 * @Description
 * @Author hjk
 * @Date 2020/9/2
 **/
public class ModelAttrPutUtil {
    /**
     * 缓存model字段名称及其数据类型，用于@ModelPara
     */
    public static final Map<Class, Map<String, Class>> fieldClassMap = new HashMap();
    /**
     * 定义model类所在位置
     */
    public static final String modelPackage = "com.hjk.waibao.mj.common.model";
    public static final String baseModelPackage = "com.hjk.waibao.mj.common.model.base";

    static {
        //加载model字段名称及其数据类型
        Set<Class<?>> classSet = ClassUtil.scanPackage(baseModelPackage);
        for (Class<?> aClass : classSet) {
            Method[] methods = aClass.getDeclaredMethods();
            LinkedList<Method> getMethodList = new LinkedList<>();
            for (Method method : methods) {
                if (method.getName().matches("get[A-Z]\\w*")) {
                    getMethodList.add(method);
                }
            }
            Map<String, Class> map = new HashMap<>(getMethodList.size());
            for (Method method : getMethodList) {
                String name = method.getName().substring(3);
                name = ((char) (name.charAt(0) + 32)) + name.substring(1);
                map.put(name, method.getReturnType());
            }
            try {
                fieldClassMap.put(Class.forName(aClass.getTypeName().replace(
                        baseModelPackage + ".Base", modelPackage + "."
                )), map);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
//        System.out.println(fieldClassMap);
    }

    public static final void setPara(Object instance, JSONObject json) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        setPara(instance, (Set) json.entrySet());
    }

    public static final void setPara(Object instance, Map<String, String> map) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        setPara(instance, (Set) map.entrySet());
    }

    public static final void setPara(Object instance, Set<Map.Entry<String, ? extends Object>> entrySet) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method setParaMethod = instance.getClass().getMethod("set", String.class, Object.class);
        for (Map.Entry<String, ?> entry : entrySet) {
            Object o = entry.getValue();
            Class c = fieldClassMap.get(instance.getClass()).get(entry.getKey());
            if (c != null) {
                //参数类型转化
                o = BaseDataConvertUtil.convert(o, c);
                try {
                    setParaMethod.invoke(instance, entry.getKey(), o);
                } catch (InvocationTargetException | IllegalAccessException e) {
                    if (e.getCause() == null || e.getCause().getMessage() == null || !e.getCause().getMessage().contains("The attribute name does not exist")) {
                        throw e;
                    }
                }
            }
        }
    }
}
